<template>
    <div class='web-camera_wrap'>
        <video id="video-camera"></video>
        <canvas v-show="snap" id="canvas-snap"></canvas>
        <div class="top-bar" v-show="snap">
          <span class="iconfont icon-JamIconschevroncircleleftf btn-left" @click="backToCamera"></span>
        </div>
        <div class="btn-bar" :style="`top:${innerHeight-210}px;`" v-show="!showScan">
          <div class="btn btn-take-photo" @mouseup="takePhoto"><span class="circle"></span></div>
        </div>   
        <div class="recognition-scan" v-show="showScan"></div>

        <v-bottom-sheet v-model="showResult">
        <v-sheet
          :color="`white ${theme.isDark ? 'darken-2' : 'lighten-4'}`"
          class="pa-3"
        >
          <div class="result-box"  v-if="videoUrl">
            <div class="video-box">
              <v-responsive :aspect-ratio="16/9">
              <video class="" width="100%" height="auto" autoplay muted controls loop>
                <source :src="videoUrl" type="video/mp4" >
                {{videoUrl}}
              </video>
              </v-responsive>
            </div>
            <h3>阆中</h3>
            <p>
              阆中，古称保宁，是四川省南充市代管的县级市，地处四川盆地北缘，位于嘉陵江中上游， [1]  秦巴山南麓，山围四面，水绕三方。东靠巴中市、仪陇县，南连南部县，西邻剑阁县，北接苍溪县。2000多年来，为巴蜀要冲，军事重镇。自元朝阆州升格为保宁府以来，阆中一直是川北地区政治、经济、文化、教育和商贸中心。
            </p>
          </div>
        </v-sheet>
      </v-bottom-sheet>
      <v-snackbar
      top
      v-model="showSnackbar"
      :timeout="timeout">
      {{ snackbarText }}

      <template v-slot:action="{ attrs }">
        <v-btn
          color="blue"
          text
          v-bind="attrs"
          @click="showSnackbar = false"
        >
          Close
        </v-btn>
      </template>
    </v-snackbar>
    </div>
</template>
<style scoped  lang="scss">
$btn-size:90px;
$btn-circle-size:60px;
.web-camera_wrap{  
  height: 100%;
}
#canvas-snap{
  display:block;
}
#video-camera{
  display:block;
}
.video-box{
  overflow: hidden;
  border-radius: 12px;
  background: transparent;
  font-size: 0;
}
.result-box{
  h3{
    margin: 36px 0 12px;
  }
}
.top-bar{
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 30px;
  padding: 30px;
  text-align:left;
  z-index:202;
}
.top-bar .btn-left{
  font-size:30px;
  color:#FFF;
}
.btn{
  border:none;
}
.btn-bar{
  position: absolute;  
  left: 0;
  right: 0;
  display: flex;
  flex-flow: row nowrap;
  justify-content: center;
  align-items: center;
  height: 210px;
}
.btn-take-photo{
  position:relative;
  width:$btn-size;
  height:$btn-size;
  padding:15px;
  background:#c4c9ca;
  border-radius:50%;
  display:flex;
  flex-flow:row nowrap;
  justify-content:center;
  align-items:center;
}
.btn-take-photo>.circle{
  display:inline-block;
  width:$btn-circle-size;
  height:$btn-circle-size;
  border-radius:50%;
  background:#FFF;
  transition:all 200ms linear;
}
.btn-take-photo:active>.circle{
  width:30px;
  height:30px;
}
.recognition-scan{
  position: absolute;
  z-index: 9;
  top: 0;
  left: 0;
  width: 840px;
  border-bottom: 3px solid #07c160;
  animation: scan 1.2s infinite;
  background: linear-gradient(180deg,transparent,#07c160);  
}
#canvas-snap{
  position: absolute;  
  top:0;
  left:0;
  z-index:8;
}
@keyframes scan {
    0% {
        height: 0
    }

    to {
        opacity: 0;
        height: 98%;
    }
}  
</style>

<style scoped>
  @import "//at.alicdn.com/t/font_2226075_jbuub0jvza.css";
</style>

<script>

export default {
  name: 'Camera',
  created(){
    this.openWebCamera()
    document.addEventListener('beforeunload', this.stopWebCamera)
  },
  mounted(){
    // this.resizeCanvas()
    
    // this.snap = 'fabc'
    // this.showResult = true    
    // this.videoUrl = '/video/2207fd6e2046c8a4fc7984ce57a0019588d11617f2ee0000b51ed541d8e1.mp4'
  },
  data(){
    return {
      videoElem: null,
      cameraStream: null,
      hasResult: false,
      videoUrl:null,    
      snap: '',  // 快照
      snackbar: false,
      snackbarText: '没有结果返回，请重新拍照识别',
      timeout: 3000,
    }
  },
  props: ['submitUrl'],
  computed:{
    showResult:{
      get(){
        if(!this.hasResult){
          this.backToCamera()
        }
        console.log('hasResult:',this.hasResult,this.videoUrl)
        return this.hasResult
      },
      set(value){
        this.hasResult = value
      }
    },
    showSnackbar: {
      get(){
        if(!this.snackbar){
          this.backToCamera()
        }
        return this.snackbar
      },
      set(value){
        this.snackbar = value
      }
    },
    innerWidth(){
      return window.innerWidth
    },
    innerHeight(){
      return window.innerHeight
    },
    showScan(){
      return this.snap&&!this.videoUrl&&!this.snackbar
    }
  },
  methods:{
    async openWebCamera(){
      console.log(this.innerWidth,this.innerHeight)
      const _this = this;
      const devices = await navigator.mediaDevices.enumerateDevices()
      const environmentCamera = devices.find(
        device => device.kind === "videoinput" && device.label.includes("facing back")
      )
      const constraints = { audio: false, video: {} }; 
      // const constraints = {video:true}
      
      if (environmentCamera) {
        constraints.video.deviceId = environmentCamera.deviceId
      } else {
        constraints.video.facingMode = {
          exact: "environment",
        }
      }
      // const constraints = {audio: true,video:{width: this.innerWidth, height: this.innerHeight,facingMode:"enviroment"}}
      console.log('设备约束',constraints)
      try{
        if (navigator.mediaDevices === undefined) {
              navigator.mediaDevices = {};
        }
        if (navigator.mediaDevices.getUserMedia === undefined) {
            navigator.mediaDevices.getUserMedia = function (constraints) {
                // 首先，如果有getUserMedia的话，就获得它
                var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;

                // 一些浏览器根本没实现它 - 那么就返回一个error到promise的reject来保持一个统一的接口
                if (!getUserMedia) {
                    return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
                }

                // 否则，为老的navigator.getUserMedia方法包裹一个Promise
                return new Promise(function (resolve, reject) {
                    getUserMedia.call(navigator, constraints, resolve, reject);
                });
            }
        }


        navigator.mediaDevices.getUserMedia(constraints)
        .then(function(stream) {
          var video = document.querySelector('video#video-camera');
          if('srcObject' in video){
            video.srcObject = stream;
          }else{
            video.src = window.URL.createObjectURL(stream)
          }
          _this.cameraStream = stream;
          video.onloadedmetadata = function() {
            video.play();
          };
          video.addEventListener('playing',()=>{
            const canvas = document.querySelector("canvas#canvas-snap");
            canvas.width = video.videoWidth
            canvas.height = video.videoHeight            
          },false)
        })
        .catch(function(err) {   // 总是在最后检查错误
          console.error(err)
          console.log(err.name + ": " + err.message); 
        });
      }catch(e){
        console.error('报错:',e)
      }
    },
    stopWebCamera(){
      const video = document.querySelector('video#video-camera');
      if (video) {
          // video.pause();
          // video.src = '';
          // video.load();
          var stream = video.srcObject;
          var tracks = stream.getTracks();

          for (var i = 0; i < tracks.length; i++) {
            var track = tracks[i];
            track.stop();
          }

          video.srcObject = null;          
      }
      const cameraStream = this.cameraStream
      if (cameraStream && cameraStream.stop) {
          cameraStream.stop();
      }
      this.cameraStream = null;
    },
    backToCamera(){
      this.showResult = false
      this.videoUrl = null
      this.snap = null
    },  
    resizeCanvas(){ // 设定canvas大小
      // let canvas = document.querySelector("canvas#canvas-snap");
    }, 
    takePhoto() {
        if(!this.cameraStream){
          this.showSnackbarWidget('未检测到相机')
          return false;
        }

        const video = document.querySelector('video#video-camera')
        //获得Canvas对象
        const canvas = document.querySelector("canvas#canvas-snap");
        // canvas.width = video.videoWidth
        // canvas.height = video.videoHeight
        // console.log('video',video.videoWidth,video.videoHeight)
        const ctx = canvas.getContext('2d');        
        ctx.drawImage(video, 0, 0);
        const pic = canvas.toDataURL("image/jpg").replace(/^data:image\/(png|jpg);base64,/,"");
        this.snap = pic;        

        this.axios.post(this.submitUrl,
        "query_img="+encodeURIComponent(pic),
        { headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, }  ,
        )
        .then(res=>{
          console.log(res)
          const data = res.data
          if(data.error == 1){  // 没有匹配到结果
            this.showSnackbarWidget('没有结果返回，请重新拍照识别')
          }else{
            switch(data.filename){
              default:
                this.videoUrl = '/video/2207fd6e2046c8a4fc7984ce57a0019588d11617f2ee0000b51ed541d8e1.mp4'
                this.showResult = true
            }

          }
        })
        .catch(err=>{
          console.log(err)
          this.showSnackbarWidget('无法访问识别服务')
        })
   
    },
    showSnackbarWidget(text){
      this.snackbar = true
      this.snackbarText = text      
    }
  },
  inject: {
    theme: {
      default: { isDark: false },
    },
  },
}
</script>